﻿using System;
using System.Management;

namespace Eflong.Management
{
    public class Win32ServiceManager
    {
        private string strPath;
        private ManagementClass managementClass;
        private ManagementScope managementScope;

        public Win32ServiceManager( )
            : this( "." , null , null )
        {
        }

        public Win32ServiceManager( string host , string userName , string password )
        {
            this.strPath = "\\\\" + host + "\\root\\cimv2:Win32_Service";
            this.managementClass = new ManagementClass( strPath );
            if ( userName != null && userName.Length > 0 )
            {
                ConnectionOptions connectionOptions = new ConnectionOptions( );
                connectionOptions.Username = userName;
                connectionOptions.Password = password;
                ManagementScope managementScope = new ManagementScope( "\\\\" + host + "\\root\\cimv2" , connectionOptions );
                this.managementClass.Scope = managementScope;
            }
        }

        /// <summary>
        /// 验证是否能连接到远程计算机
        /// </summary>
        /// <param name="host"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static bool RemoteConnectValidate( string host , string userName , string password )
        {
            return RemoteConnectValidate( host , userName , password , "" );
        }

        public static bool RemoteConnectValidate( string host , string userName , string password , string path )
        {
            ConnectionOptions connectionOptions = new ConnectionOptions( );

            //connectionOptions.Authentication = AuthenticationLevel.PacketPrivacy;

            connectionOptions.Username = userName;
            connectionOptions.Password = password;
            connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
            connectionOptions.EnablePrivileges = true;

            string commandStr = @"\\" + host + @"\root\cimv2"; // \\192.168.0.254\d$\EflongData
            ManagementPath managementPath = new ManagementPath( commandStr );
            ManagementScope managementScope = new ManagementScope( managementPath , connectionOptions );

            try
            {
                managementScope.Connect( );
                if ( !string.IsNullOrEmpty( path ) )
                {
                    ObjectGetOptions options = new ObjectGetOptions( );
                    path = "win32_logicaldisk";
                    ManagementObject disk = new ManagementObject( managementScope , new ManagementPath( path ) , options );
                    disk.Get( );
                }
            }
            catch
            {
            }
            return managementScope.IsConnected;
        }

        public static void AccessPath( string server , string path )
        {
            ManagementObject disk = new ManagementObject( "win32_logicaldisk.deviceid=\"c:\"" );

            disk.Get( );
        }

        // 获取指定服务属性的值
        public object GetServiceValue( string serviceName , string propertyName )
        {
            ManagementObject mo = this.managementClass.CreateInstance( );
            mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serviceName + "\"" );
            return mo[ propertyName ];
        }

        // 获取所连接的计算机的所有服务数据
        public string[ , ] GetServiceList( )
        {
            string[ , ] services = new string[ this.managementClass.GetInstances( ).Count , 4 ];
            int i = 0;
            foreach ( ManagementObject mo in this.managementClass.GetInstances( ) )
            {
                services[ i , 0 ] = ( string )mo[ "Name" ];
                services[ i , 1 ] = ( string )mo[ "DisplayName" ];
                services[ i , 2 ] = ( string )mo[ "State" ];
                services[ i , 3 ] = ( string )mo[ "StartMode" ];
                i++;
            }
            return services;
        }

        // 获取所连接的计算机的指定服务数据
        public string[ , ] GetServiceList( string serverName )
        {
            return GetServiceList( new string[ ] { serverName } );
        }

        // 获取所连接的计算机的的指定服务数据
        public string[ , ] GetServiceList( string[ ] serverNames )
        {
            string[ , ] services = new string[ serverNames.Length , 4 ];
            ManagementObject mo = this.managementClass.CreateInstance( );
            for ( int i = 0; i < serverNames.Length; i++ )
            {
                mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serverNames[ i ] + "\"" );
                services[ i , 0 ] = ( string )mo[ "Name" ];
                services[ i , 1 ] = ( string )mo[ "DisplayName" ];
                services[ i , 2 ] = ( string )mo[ "State" ];
                services[ i , 3 ] = ( string )mo[ "StartMode" ];
            }
            return services;
        }

        // 开始指定的服务
        public string StartService( string serviceName )
        {
            string strRst = null;
            ManagementObject mo = this.managementClass.CreateInstance( );
            mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serviceName + "\"" );
            try
            {
                if ( ( string )mo[ "State" ] == "Stopped" )//!(bool)mo["AcceptStop"]
                    mo.InvokeMethod( "StartService" , null );
            }
            catch ( ManagementException e )
            {
                strRst = e.Message;
            }
            return strRst;
        }

        // 暂停指定的服务
        public string PauseService( string serviceName )
        {
            string strRst = null;
            ManagementObject mo = this.managementClass.CreateInstance( );
            mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serviceName + "\"" );
            try
            {
                //判断是否可以暂停
                if ( ( bool )mo[ "acceptPause" ] && ( string )mo[ "State" ] == "Running" )
                    mo.InvokeMethod( "PauseService" , null );
            }
            catch ( ManagementException e )
            {
                strRst = e.Message;
            }
            return strRst;
        }

        // 恢复指定的服务
        public string ResumeService( string serviceName )
        {
            string strRst = null;
            ManagementObject mo = this.managementClass.CreateInstance( );
            mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serviceName + "\"" );
            try
            {
                //判断是否可以恢复
                if ( ( bool )mo[ "acceptPause" ] && ( string )mo[ "State" ] == "Paused" )
                    mo.InvokeMethod( "ResumeService" , null );
            }
            catch ( ManagementException e )
            {
                strRst = e.Message;
            }
            return strRst;
        }

        // 停止指定的服务
        public string StopService( string serviceName )
        {
            string strRst = null;
            ManagementObject mo = this.managementClass.CreateInstance( );
            mo.Path = new ManagementPath( this.strPath + ".Name=\"" + serviceName + "\"" );
            try
            {
                //判断是否可以停止
                if ( ( bool )mo[ "AcceptStop" ] )
                {//(string)mo["State"]=="Running"
                    mo.InvokeMethod( "StopService" , null );
                }
            }
            catch ( ManagementException e )
            {
                strRst = e.Message;
            }
            return strRst;
        }
    }

    public class WindowsManager
    {
        public static bool RemoteConnectValidate( string host , string userName , string password )
        {
            ConnectionOptions co = new ConnectionOptions( );
            co.Username = userName;
            co.Password = password;
            co.Authentication = AuthenticationLevel.PacketPrivacy;

            string path = @"\\" + host + @"\root\cimv2:Win32_LogicalDisk"; // \\192.168.0.254\d$\EflongData
            ManagementPath p = new ManagementPath( path );
            System.Management.ManagementScope ms = new ManagementScope( p , co );
            try
            {
                ms.Connect( );
                if ( ms.IsConnected )
                {
                    ManagementObject disk = new ManagementObject( ms ,
                        new ManagementPath( "Win32_logicaldisk='d:'" ) , null );
                    disk.Get( );
                }
            }
            catch ( Exception ex )
            {
                Console.WriteLine( ex.Message );
            }

            return ms.IsConnected;
        }

        public static void ShowAllDisk( string host )
        {
            ManagementClass management = new ManagementClass( "root\\CIMV2:Win32_LogicalDisk" );
            ManagementObjectCollection col = management.GetInstances( );
            foreach ( ManagementObject o in col )
            {
                object value = o.GetPropertyValue( "DriveType" );
                if ( value != null )
                {
                    if ( Convert.ToInt32( value.ToString( ) ) == 5 )
                    {
                        if ( o.Properties[ "VolumeName" ].Value != null )
                        {
                            string volDir = o.Properties[ "DeviceID" ].Value.ToString( );

                            //if (this.OnShowDialog("Would you like to rip the current Disc?", ToolTipIcon.Info) == DialogResult.Yes)
                            {
                                Console.WriteLine( "Disc In" );
#if DEBUG

                                foreach ( PropertyData data in o.Properties )
                                {
                                    if ( data.Value == null )
                                    {
                                        Console.WriteLine( data.Name + ": " );
                                    }
                                    else
                                    {
                                        Console.WriteLine( data.Name + ": " + data.Value.ToString( ) );
                                    }
                                }
#endif

                                //Do Stuff
                            }
                        }
                        else
                        {
                            Console.WriteLine( "No Disc" );
                        }
                    }
                }
            }
        }
    }
}